home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 January / enter-2004-01.iso / files / maxima-5.9.0.exe / {app} / share / maxima / 5.9.0 / emacs / smart-complete.el < prev    next >
Encoding:
Text File  |  2003-02-09  |  4.9 KB  |  155 lines

  1. ;; This file is part of GNU Emacs.
  2. ;; Copyright (C) 1998 William F. Schelter
  3.  
  4. ;; GNU Emacs is distributed in the hope that it will be useful, but
  5. ;; WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  6. ;; to anyone for the consequences of using it or for whether it serves
  7. ;; any particular purpose or works at all, unless he says so in writing.
  8. ;; Refer to the GNU Emacs General Public License for full details.
  9.  
  10. ;; Everyone is granted permission to copy, modify and redistribute GNU
  11. ;; Emacs, but only under the conditions described in the GNU Emacs
  12. ;; General Public License.  A copy of this license is supposed to have
  13. ;; been given to you along with GNU Emacs so you can know your rights and
  14. ;; responsibilities.  It should be in a file named COPYING.  Among other
  15. ;; things, the copyright notice and this notice must be preserved on all
  16. ;; copies.
  17.  
  18.  
  19.  
  20. ;; By Bill Schelter wfs@math.utexas.edu
  21.  
  22. ;; Completion on forms in the buffer.   Does either a line or an sexp.
  23. ;; Uses the current prompt and the beginning of what you have typed.
  24. ;; Thus If the buffer contained
  25.  
  26. ;; (dbm:3) load("jo"
  27. ;; (C11) lo("ji")
  28. ;; (gdb) last
  29. ;; maxima>>4
  30. ;; /home/bil# ls 
  31. ;; then if you are at a prompt 
  32. ;; "(C15) l"  would match lo("ji")  only, not "last", not "ls" nor load("
  33. ;; and the commands with the (gdb) prompt would only match ones
  34. ;; starting with (gdb) ..
  35.  
  36.  
  37. ;; also if the command is a lisp sexp and this would be longer than the
  38. ;; current line, it grabs the whole thing.  sometimes we have different
  39. ;; prompts, for different programs and we dont want to confuse the input
  40. ;; from one with input for another.  Generally the prompt matches a
  41. ;; previous prompt, with numbers matching any number, and if there are
  42. ;; '/' then match anything up to a shell prompt terminator.  Note it does
  43. ;; this without additional consing or building up huge lists of inputs.
  44.  
  45.  
  46. (if (boundp 'comint-mode-map)
  47.     (define-key comint-mode-map "\ep" 'smart-complete)
  48.   )
  49.  
  50. (if (boundp 'sshell-mode-map)
  51.     (define-key sshell-mode-map "\ep" 'smart-complete)
  52.    (define-key sshell-mode-map "\M-p" 'smart-complete)
  53.   )
  54.  
  55. (defun get-match-n (i )
  56.   (buffer-substring (match-beginning i) (match-end i)))
  57.  
  58. (defun smart-complete ()
  59.   "Begin to type the command and then type M-p.  You will be
  60.  offered in the minibuffer a succession of choices, which
  61.  you can say 'n' to to get the next one, or 'y' or 'space'
  62.  to grab the current one.
  63.  
  64.  Thus to get the last command starting with 'li' you type
  65.  liM-py
  66. "
  67.   (interactive )
  68.   (let ((point (point)) new str tem prompt)
  69.   (save-excursion
  70.     (beginning-of-line)
  71.     (cond ((looking-at sshell-prompt-pattern)
  72.        (setq prompt (get-match-n 0))
  73.        (setq str (buffer-substring (match-end 0) point)))
  74.       (t (error "Your prompt on this line does not match sshell-prompt-pattern")))
  75.  
  76.     (setq new (smart-complete2 prompt str))
  77.     )
  78.   (cond (new
  79.      (delete-region (setq tem (- point (length str))) point)
  80.      (goto-char tem)
  81.      (insert new)))))
  82.  
  83. (defun smart-complete2 (prompt str)
  84.   (let ((pt (point)) found
  85.     (pat (concat (regexp-for-this-prompt prompt)
  86.              "\\(" (regexp-quote str) "\\)" ))
  87.     offered (not-yet t)
  88.     )
  89.     (setq bill pat)
  90.     (while (and  not-yet
  91.          (re-search-backward pat nil t))
  92.       (goto-char (match-beginning 1))
  93.       (setq at (match-beginning 1))
  94.       (goto-char at)
  95.       (setq this (buffer-substring at
  96.           (save-excursion (end-of-line) (point))))
  97.        (or  (member this offered)
  98.         (equal this str)
  99.         (progn (setq offered (cons this offered))
  100.            ;; do this so the display does not shift...
  101.            (goto-char pt)
  102.            (setq not-yet
  103.              (not (y-or-n-p (concat "Use: " this " "))))))
  104.        (cond (not-yet (goto-char at) (beginning-of-line) (forward-char -1))
  105.          (t (setq found
  106.               (save-excursion
  107.             (buffer-substring
  108.              at
  109.              (progn (goto-char at)
  110.                 (max (save-excursion
  111.                        (end-of-line) (point))
  112.                      (save-excursion
  113.                        (forward-sexp 1)(point)))
  114.                 )))))))
  115.     (or found (message "No more matches"))
  116.     found
  117.     ))
  118.  
  119.  
  120. ;; return a regexp for this prompt but with numbers replaced.
  121.  
  122. (defun split-string (s bag)
  123.   (cond ((equal (length s) 0) '(""))
  124.     ((string-match bag s)
  125.      (if (= (match-beginning  0) 0)
  126.         (cons "" (split-string (substring s (match-end 0)) bag))
  127.        (cons (substring s 0 (match-beginning 0))
  128.          (split-string (substring s (match-end 0)) bag))))
  129.     (t (cons s nil))))
  130.  
  131. ;; Return a regexp which matches the current prompt, and which
  132. ;; allows things like
  133. ;; "/foo/bar# " to match  "any# "
  134. ;; "(C12) " to match  "(C1002) " but not (gdb) nor "(D12) "
  135. ;; if the prompt appears to be a pathname (ie has /) then
  136. ;; allow any beginning, otherwise numbers match numbers...
  137. (defun regexp-for-this-prompt (prompt )
  138.   (let ((wild (cond ((string-match "/" prompt) "[^ >#%()]+")
  139.             (t "[0-9]+"))))
  140.   (let ((tem (split-string prompt wild)) (ans ""))
  141.     (while tem
  142.       (setq ans (concat ans (regexp-quote (car tem))))
  143.       (cond ((cdr tem) (setq ans (concat ans wild))))
  144.       (setq tem (cdr tem)))
  145.     ans)))
  146.  
  147.   
  148. (provide 'smart-complete)
  149.  
  150.   
  151.       
  152.       
  153.     
  154.  
  155.